package com.wonders.demo.core.shiro.realms;

import com.wonders.demo.core.holder.ApplicationContextHolder;
import com.wonders.demo.core.shiro.ShiroUser;
import com.wonders.demo.module.po.UserPo;
import com.wonders.demo.module.service.UserService;
import com.wonders.demo.utils.MyByteSource;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashSet;
import java.util.Set;

/**
 * @author wonders
 */
public class CustomRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("====doGetAuthorizationInfo====");
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        UserService userService = ApplicationContextHolder.getBean(UserService.class);

        ShiroUser shiroUser = userService.getAuthInfoByName(primaryPrincipal);

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Set roleSet = new HashSet<>();
        Set menuSet = new HashSet<>();
        roleSet.addAll(shiroUser.getRoles());
        menuSet.addAll(shiroUser.getMenus());
        authorizationInfo.setRoles(roleSet);
        authorizationInfo.setStringPermissions(menuSet);
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        SimpleAuthenticationInfo simpleAuthenticationInfo = null;
        String principal = (String) authenticationToken.getPrincipal();
        UserService userService = ApplicationContextHolder.getBean(UserService.class);
        UserPo user = userService.getUserByName(principal);
        if (user != null) {
            // 认证根本不会用到SimpleAuthenticationInfo的第一个参数。shiro只要返回一个不为null的AuthenticationInfo就认为用户名存在。
            // 只要token中密码+salt 和 数据库中密码一致就认为 密码正确。
            simpleAuthenticationInfo = new SimpleAuthenticationInfo(principal, user.getPassword(), new MyByteSource(user.getSalt()), this.getName());
        }
        return simpleAuthenticationInfo;
    }

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashIterations(1024);
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        super.setCredentialsMatcher(hashedCredentialsMatcher);
    }


}
